/* ========================================================================
 * ColorPicker.js [1.5.0+]
 * ========================================================================
 * Copyright (c) 2016 cnezsoft.com; Licensed MIT
 * ======================================================================== */
(function($) {
  'use strict';
  var name = 'colorPicker'; // modal name
  var TEAMPLATE = '<div class="colorpicker"><button type="button" class="hui-btn hui-dropdown-toggle" data-toggle="dropdown"><span class="cp-title"></span><i class="ic"></i></button><ul class="hui-dropdown-menu clearfix"></ul></div>';
  var LANG = {
    zh_cn: {
      errorTip: "不是有效的颜色值"
    },
    zh_tw: {
      errorTip: "不是有效的顏色值"
    },
    en: {
      errorTip: "Not a valid color value"
    }
  };

  // The ColorPicker modal class
  var ColorPicker = function(element, options) {
    this.name = name;
    this.$ = $(element);

    this.getOptions(options);
    this.init();
  };

  // default options
  ColorPicker.DEFAULTS = {
    colors: ['#00BCD4', '#388E3C', '#3280fc', '#3F51B5', '#9C27B0', '#795548', '#F57C00', '#F44336', '#E91E63'],
    pullMenuRight: true,
    wrapper: 'btn-wrapper',
    tileSize: 30,
    lineCount: 5,
    optional: true,
    tooltip: 'top',
    icon: 'caret-down',
    // btnTip: 'Tool tip in button'
  };

  ColorPicker.prototype.init = function() {
    var options = this.options,
    that = this;

    this.$picker = $(TEAMPLATE).addClass(options.wrapper);
    this.$picker.find('.cp-title').toggle(options.title !== undefined).text(options.title);
    this.$menu = this.$picker.find('.hui-dropdown-menu').toggleClass('pull-right', options.pullMenuRight);
    this.$btn = this.$picker.find('.hui-btn.hui-dropdown-toggle');
    this.$btn.find('.ic').addClass('icon-' + options.icon);
    if (options.btnTip) {
      this.$picker.attr('data-toggle', 'tooltip').tooltip({
        title: options.btnTip,
        placement: options.tooltip,
        container: 'body'
      });
    }
    this.$.attr('data-provide', null).after(this.$picker);

    // init colors
    this.colors = {};
    $.each(this.options.colors,
    function(idx, rawColor) {
      if ($.zui.Color.isColor(rawColor)) {
        var color = new $.zui.Color(rawColor);
        that.colors[color.toCssStr()] = color;
      }
    });

    this.updateColors();
    var that = this;
    this.$picker.on('click', '.cp-tile',
    function() {
      that.setValue($(this).data('color'));
    });
    var $input = this.$;
    var setInputColor = function() {
      var val = $input.val();
      var isColor = $.zui.Color.isColor(val);
      $input.parent().toggleClass('has-error', !isColor && !(options.optional && val === ''));
      if (isColor) {
        that.setValue(val, true);
      } else {
        if (options.optional && val === '') {
          $input.tooltip('hide');
        } else if (!$input.is(':focus')) {
          $input.tooltip('show', options.errorTip);
        }
      }
    }
    if ($input.is('input:not([type=hidden])')) {
      if (options.tooltip) {
        $input.attr('data-toggle', 'tooltip').tooltip({
          trigger: 'manual',
          placement: options.tooltip,
          tipClass: 'tooltip-danger',
          container: 'body'
        });
      }
      $input.on('keyup paste input change', setInputColor);
    } else {
      $input.appendTo(this.$picker);
    }
    setInputColor();
  };

  ColorPicker.prototype.addColor = function(color) {
    var hex = color.toCssStr(),
    options = this.options;

    if (!this.colors[hex]) {
      this.colors[hex] = color;
    }

    var $a = $('<a href="###" class="cp-tile"></a>', {
      titile: color
    }).data('color', color).css({
      'color': color.contrast().toCssStr(),
      'background': hex,
      'border-color': color.luma() > 0.43 ? '#ccc': 'transparent'
    }).attr('data-color', hex);
    this.$menu.append($('<li/>').css({
      width: options.tileSize,
      height: options.tileSize
    }).append($a));
    if (options.optional) {
      this.$menu.find('.cp-tile.empty').parent().detach().appendTo(this.$menu);
    }
  };

  ColorPicker.prototype.updateColors = function(colors) {
    var $picker = this.$picker,
    $menu = this.$menu.empty(),
    options = this.options,
    colors = colors || this.colors,
    that = this;
    var bestLineCount = 0;
    $.each(colors,
    function(idx, color) {
      that.addColor(color);
      bestLineCount++;
    });
    if (options.optional) {
      var $li = $('<li><a class="cp-tile empty" href="###"></a></li>').css({
        width: options.tileSize,
        height: options.tileSize
      });
      this.$menu.append($li);
      bestLineCount++;
    }
    $menu.css('width', Math.min(bestLineCount, options.lineCount) * options.tileSize + 6);
  };

  ColorPicker.prototype.setValue = function(color, notSetInput) {
    var options = this.options;
    this.$menu.find('.cp-tile.active').removeClass('active');
    var hex = '';
    if (color) {
      var c = new $.zui.Color(color);
      hex = c.toCssStr().toLowerCase();
      this.$btn.css({
        background: hex,
        color: c.contrast().toCssStr(),
        borderColor: c.luma() > 0.43 ? '#ccc': hex
      });
      if (!this.colors[hex]) {
        this.addColor(c);
      }
      if (!notSetInput && this.$.val().toLowerCase() !== hex) {
        this.$.val(hex).trigger('change');
      }
      this.$menu.find('.cp-tile[data-color=' + hex + ']').addClass('active');
      this.$.tooltip('hide');
      this.$.trigger('colorchange', c);
    } else {
      this.$btn.attr('style', null);
      if (!notSetInput && this.$.val() !== '') {
        this.$.val(hex).trigger('change');
      }
      if (options.optional) {
        this.$.tooltip('hide');
      }
      this.$menu.find('.cp-tile.empty').addClass('active');
      this.$.trigger('colorchange', null);
    }

    if (options.updateBorder) {
      $(options.updateBorder).css('border-color', hex);
    }
    if (options.updateBackground) {
      $(options.updateBackground).css('background-color', hex);
    }
    if (options.updateColor) {
      $(options.updateText).css('color', hex);
    }
    if (options.updateText) {
      $(options.updateText).text(hex);
    }
  };

  // Get and init options
  ColorPicker.prototype.getOptions = function(options) {
    var thisOptions = $.extend({},
    ColorPicker.DEFAULTS, this.$.data(), options);
    if (typeof thisOptions.colors === 'string') thisOptions.colors = thisOptions.colors.split(',');
    var lang = (thisOptions.lang || $.zui.clientLang()).toLowerCase();
    if (!thisOptions.errorTip) {
      thisOptions.errorTip = LANG[lang].errorTip;
    }
    if (!$.fn.tooltip) thisOptions.btnTip = false;
    this.options = thisOptions;
  };

  // Extense jquery element
  $.fn.colorPicker = function(option) {
    return this.each(function() {
      var $this = $(this);
      var data = $this.data(name);
      var options = typeof option == 'object' && option;

      if (!data) $this.data(name, (data = new ColorPicker(this, options)));

      if (typeof option == 'string') data[option]();
    });
  };

  $.fn.colorPicker.Constructor = ColorPicker;

  // Auto call colorPicker after document load complete
  $(function() {
    $('[data-provide="colorpicker"]').colorPicker();
  });
} (jQuery));